<?php
/**
 * 
 * dispatch the request to current controller is my responsibility
 * @author Leo Ning <leo.ning@like18.com>
 *
 */

class Dispatcher {
	public static function run($module, $action = 'index', $sub = '') {
		$dispatcher = new Dispatcher ();
		$dispatcher->dispatch ( '/' . $module . '/' . $action, false, $sub );
	}
	/**
	 * 分发请求给控制器处理
	 * 
	 * @param string $url 当前请求URL
	 */
	public function dispatch($url, $afterEnabled = false, $sub = '') {
		Response::begin ( $url );
		if (preg_match ( '#.*\.(js|css|jpg|gif|bmp|png|php)$#i', $url )) {
			Response::error ( 'Not Found', 404, true );
		}
		$url = empty ( $url ) ? '/' : $url;
		// 通知插件，系统将要分发$url
		$end_dispatch = fire ( 'before_dispatch', $url );
		if ($end_dispatch !== true) {
			$amod = '';
			$dest = Router::getRoute ( $url );
			if (isset ( $dest ['module'] )) {
				$amod = $dest ['module'] = strtolower ( $dest ['module'] );
			}else if (isset ( $dest ['plugin'] )) {
				$amod = $dest ['plugin'] = strtolower ( $dest ['plugin'] );
			}
			$dest ['action'] = ucwords ( $dest ['action'] );
			$action = $this->load_action ( $dest, $url, $sub );
			if ($action == null && $afterEnabled && Router::hasAfterRoutes ()) {
				$dest = Router::getRoute ( $url, true ); //使用后路由再加载一次
				if (isset ( $dest ['module'] )) {
					$amod = $dest ['module'] = strtolower ( $dest ['module'] );
				}else if (isset ( $dest ['plugin'] )) {
					$amod = $dest ['plugin'] = strtolower ( $dest ['plugin'] );
				}
				$action = $this->load_action ( $dest, $url, $sub );
			}
			if ($action == null) { // 未加载到控制器					
				Response::error ( "未加载到控制器:" . $amod . '.' . (empty ( $sub ) ? '' : $sub . '.') . $dest ['action'], 404 );
			} else {
				$stop = fire ( 'before_action_execute', $action, $dest, $url );
				if ($stop !== true) {
					$view = $action->execute ( $dest ['params'] );
					if ($view != null && $view instanceof View) {
						$view->setDefaultTpl ( $dest ['action'] );
						$content = $view->render ( $action, $amod );
						if ($content !== null || $content !== false) {
							$view->setHeader ();
							echo $content;
						}
					}
				}
			}
		}
		Response::close ( false );
	}
	/**
	 *
	 *
	 * 加载Action
	 * 
	 * @param $dest array       	
	 * @param $url string       	
	 * @return Action
	 */
	private function load_action($dest, $url, $sub = '') {
		global $__global;
		$dest = apply_filter ( 'before_load_action', $dest );
		$action = $dest ['action'];		
		$abase = DS . CONTROLLER_DIR . DS . (empty ( $sub ) ? '' : $sub . DS) . $action . '.php';
		if (isset ( $dest ['plugin'] )) {//加载插件中的action
			$module = $dest ['plugin'];
			$afile = PLUGIN_PATH . $dest ['plugin'] . $abase;
			$__global ['is_plugin_action'] = true;
		} else {
			$module = $dest ['module'];
			$afile = MODULE_PATH . $dest ['module'] . $abase;
			if (is_readable ( $afile ) && is_file ( $afile )) {
				$__global ['is_plugin_action'] = false;
			}else{
				$afile = PLUGIN_PATH . $dest ['module'] . $abase;
				$__global ['is_plugin_action'] = true;
			}
		}
		if (is_readable ( $afile ) && is_file ( $afile )) {
			include $afile;
			if (class_exists ( $action ) && is_subclass_of ( $action, 'Action' )) {
				return new $action ( $url, $module );
			}
		}
		return null;
	}
}